package com.terrynoya.fight.stateMachine.triggers
{
	import com.terrynoya.fight.char.Character;
	import com.terrynoya.fight.combat.CharacterBind;
	import com.terrynoya.fight.combat.HitDefinition;
	import com.terrynoya.fight.emuns.AttackEffect;
	import com.terrynoya.fight.emuns.HitAnimationType;
	import com.terrynoya.fight.emuns.StateTypeEnum;
	import com.terrynoya.fight.emuns.SymbolType;
	import com.terrynoya.fight.evaluation.Node;
	import com.terrynoya.fight.evaluation.ParseState;

	public class GetHitVar
	{
		public function GetHitVar()
		{
			
		}
		
		public static function eval(state:Object,node:Node):*
		{
			var chara:Character = Character(state);
			if(chara == null)
			{
				return null;
			}
			
			var type:String = node.arguments[0];
			switch(type)
			{
				case "animtype":
				{
					return getAnimType(chara);
					break;
				}
				case "groundtype":
				{
					return getGroundType(chara);
					break;
				}
				case "fall":
				{
					return getIsFalling(chara);
					break;
				}
				case "yaccel":
				{
					return getYAccel(chara);
					break;
				}
				case "airtype":
				{
					return getAirHitType(chara); 
					break;
				}
				case "yvel":
				{
					return getHitVelocityY(chara);
					break;
				}
				case "fall.yvel":
				{
					return getFallVelocityY(chara);
					break;
				}
				case "slidetime":
				{
					return getSlideTime(chara);
					break;
				}
				case "isbound":
				{
					return getIsBound(chara);
					break;
				}
			}
			return 0;
		}
		
		private static function getIsBound(chara:Character):Boolean
		{
			var bind:CharacterBind = chara.bind;
			return bind.isActive == true && bind.isTargetBind == true;
		}
		
		private static function getSlideTime(chara:Character):int
		{
			var hitDef:HitDefinition = chara.defensiveInfo.hitDef;
			if(chara.defensiveInfo.blocked)
			{
				return hitDef.guardSlideTime;
			}
			else
			{
				return hitDef.groundSlideTime;
			}
		}
		
		private static function getFallVelocityY(chara:Character):Number
		{
			return chara.defensiveInfo.hitDef.fallVelocityY;
		}
		
		private static function getHitVelocityY(chara:Character):Number
		{
			return chara.defensiveInfo.getHitVelocity().y;
		}
		
		private static function getAirHitType(chara:Character):int
		{
			switch(chara.defensiveInfo.hitDef.airAttackEffect)
			{
				case AttackEffect.High:
				{
					return 1;					
					break;
				}
				case AttackEffect.Low:
				{
					return 2;					
					break;
				}
				case AttackEffect.Trip:
				{
					return 3;					
					break;
				}
				default:
				{
					return 4;
					break;
				}
			}
		}
		
		private static function getYAccel(chara:Character):Number
		{
			return chara.defensiveInfo.hitDef.yAcceleration;
		}
		
		private static function getIsFalling(chara:Character):Boolean
		{
			return chara.defensiveInfo.falling;
		}
		
		private static function getGroundType(chara:Character):int
		{
			switch(chara.defensiveInfo.hitDef.groundAttackEffect)
			{
				case AttackEffect.High:
				{
					return 1;
					break;
				}
				case AttackEffect.Low:
				{
					return 2;
					break;
				}
				case AttackEffect.Trip:
				{
					return 3;
					break;
				}
			}
			return 0;
		}
		
		private static function getAnimType(chara:Character):int
		{
			var hat:int = HitAnimationType.Light;
			if(chara.defensiveInfo.falling)
			{
				hat = chara.defensiveInfo.hitDef.fallAnimationType;
			}
			else if(chara.defensiveInfo.hitStateType == StateTypeEnum.Airborne)
			{
				hat = chara.defensiveInfo.hitDef.airAnimationType;
			}
			else
			{
				hat = chara.defensiveInfo.hitDef.groundAnimationType;
			}
			switch(hat)
			{
				case HitAnimationType.Light:
				{
					return 0;
					break;
				}
				case HitAnimationType.Medium:
				{
					return 1;
					break;
				}
				case HitAnimationType.Hard:
				{
					return 2;
					break;
				}
				case HitAnimationType.Back:
				{
					return 3;
					break;
				}
				case HitAnimationType.Up:
				{
					return 4;
					break;
				}
				case HitAnimationType.DiagUp:
				{
					return 5;
					break;
				}
			}
			return 0;
		}
		
		public static function parse(state:ParseState):Node
		{
			if(state.currentSymbol != SymbolType.LeftParen)
			{
				return null;
			}
			state.tokenIndex ++;
			
			if(state.currentToken == null)
			{
				return null;
			}
			
			var constant:String = state.currentToken.text;
			state.baseNode.arguments.push(constant);
			state.tokenIndex ++;
			
			if(state.currentSymbol != SymbolType.RightParen)
			{
				return null;
			}
			state.tokenIndex ++;
			
			return state.baseNode;
		}
	}
}